package com.example.demo.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.example.demo.config.BaseMessageConf;
import com.example.demo.entity.DTO.WeConResultBaseDTO;
import com.example.demo.entity.QUERY.WeConDepartmentQuery;
import io.itit.itf.okhttp.FastHttpClient;
import io.itit.itf.okhttp.Response;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

/**
 * wechat http请求工具类
 *
 * @author jack
 * @data 2021/8/11 3:37 下午
 */
@Slf4j
public class WeChatHttpClient {

  public final static List<String> resultKey = Arrays.asList("errcode", "errmsg");


  /**
   * get请求
   *
   * @param url
   * @param param
   * @param resultType 返回对象类型
   * @return
   */
  public static <T> T doGetByEntity(String url, Object param, Class<T> resultType) {
    try {
      Response response = FastHttpClient.get().url(url).addParams(param).build().execute();
      if (response.isSuccessful()) {
        String result = response.string();
        WeConResultBaseDTO weConResultBaseDTO = GsonUtils
            .fromJson(result, WeConResultBaseDTO.class);
        if (!weConResultBaseDTO.getErrcode().equals(0)) {
          log.error(result);
          throw new RuntimeException(weConResultBaseDTO.getErrmsg());
        }
        return GsonUtils.fromJson(result, resultType);
      } else {
        log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR, url, response.message());
        throw new RuntimeException(response.message());
      }

    } catch (Exception e) {
      log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR + ":{}", url);
      e.printStackTrace();
    }
    return null;
  }

  /**
   * get请求
   *
   * @param url
   * @param param
   * @param resultType
   * @param <T>
   * @return
   */
  public static <T> List<T> doGetListByMap(String url, Map<String, String> param,
      Class<T> resultType) {
    try {
      // 过滤并截取ACCESS_TOKE 参数，重新拼接
      String[] split = url.split("\\?access_token=");
      if (split.length < 2) {
        log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR + ":{}", url);
        throw new RuntimeException(BaseMessageConf.HTTP_CLIENT_SEND_ERROR);
      }
      url = split[0];
      param.put("access_token", split[1]);
      Response response = FastHttpClient.get().url(url).addParams(param).build().execute();
      if (response.isSuccessful()) {
        String result = response.string();
        WeConResultBaseDTO weConResultBaseDTO = GsonUtils
            .fromJson(result, WeConResultBaseDTO.class);
        if (!weConResultBaseDTO.getErrcode().equals(0)) {
          log.error(result);
          throw new RuntimeException(weConResultBaseDTO.getErrmsg());
        }

        return GsonUtils.listFromJson(filterResultReturnOne(result), resultType);
      } else {
        log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR, url, response.message());
        throw new RuntimeException(response.message());
      }

    } catch (Exception e) {
      log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR + ":{}", url);
      e.printStackTrace();
    }
    return null;
  }

  public static void doGetByMap(String url, Map<String, String> param) {
    try {
      // 过滤并截取ACCESS_TOKE 参数，重新拼接
      String[] split = url.split("\\?access_token=");
      if (split.length < 2) {
        log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR + ":{}", url);
        throw new RuntimeException(BaseMessageConf.HTTP_CLIENT_SEND_ERROR);
      }
      url = split[0];
      param.put("access_token", split[1]);
      Response response = FastHttpClient.get().url(url).addParams(param).build().execute();
      if (response.isSuccessful()) {
        String result = response.string();
        WeConResultBaseDTO weConResultBaseDTO = GsonUtils
            .fromJson(result, WeConResultBaseDTO.class);
        if (!weConResultBaseDTO.getErrcode().equals(0)) {
          log.error(result);
          throw new RuntimeException(weConResultBaseDTO.getErrmsg());
        }
        return;

      } else {
        log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR, url, response.message());
        throw new RuntimeException(response.message());
      }

    } catch (Exception e) {
      log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR + ":{}", url);
      e.printStackTrace();
    }
  }

  public static InputStream doGetInputStreamByMap(String url, Map<String, String> param) {
    try {
      // 过滤并截取ACCESS_TOKE 参数，重新拼接
      String[] split = url.split("\\?access_token=");
      if (split.length < 2) {
        log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR + ":{}", url);
        throw new RuntimeException(BaseMessageConf.HTTP_CLIENT_SEND_ERROR);
      }
      url = split[0];
      param.put("access_token", split[1]);
      InputStream is = FastHttpClient.get().url(url).addParams(param).build().execute()
          .byteStream();
      return is;

    } catch (Exception e) {
      log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR + ":{}", url);
      e.printStackTrace();
    }
    return null;
  }

  /**
   * get 请求返回 ，返回单个数据
   *
   * @param url
   * @return 简单，单一
   */
  public static String doGetSingleReturn(String url) {
    try {
      Response response = FastHttpClient.get().url(url).build().execute();
      if (response.isSuccessful()) {
        String result = response.string();
        WeConResultBaseDTO weConResultBaseDTO = GsonUtils
            .fromJson(result, WeConResultBaseDTO.class);
        if (!weConResultBaseDTO.getErrcode().equals(0)) {
          log.error(result);
          throw new RuntimeException(weConResultBaseDTO.getErrmsg());
        }
        return filterResultReturnOne(result);
      } else {
        log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR, url, response.message());
        throw new RuntimeException(response.message());
      }

    } catch (Exception e) {
      log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR + ":{}", url);
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 过滤api数据返回单一结果
   *
   * @param result
   * @return
   */
  public static String filterResultReturnOne(String result) {
    // 单参数返回过滤默认 返回参数
    Map<String, Object> map = (Map) JSONObject.parse(result);
    Optional<Object> optional = map.entrySet().stream()
        .filter(e -> !resultKey.contains(e.getKey()))
        .map(e -> e.getValue())
        .findFirst();
    if (optional.isPresent()) {
      return optional.get().toString();
    }
    return null;
  }

  /**
   * post 请求返回 结果的单个参数
   *
   * @param url
   * @param body
   * @return
   */
  public static String doPostSingleReturnByParams(String url, JSON body) {
    try {
      System.out.println(body.toJSONString());
      Response response = FastHttpClient.post().url(url)
          .body(body.toJSONString()).build()
          .execute();
      if (response.isSuccessful()) {
        String result = response.string();
        WeConResultBaseDTO weConResultBaseDTO = GsonUtils
            .fromJson(result, WeConResultBaseDTO.class);
        if (!weConResultBaseDTO.getErrcode().equals(0)) {
          log.error(result);
          throw new RuntimeException(weConResultBaseDTO.getErrmsg());
        }
        return filterResultReturnOne(result);
      } else {
        log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR, url, response.message());
        throw new RuntimeException(response.message());
      }

    } catch (Exception e) {
      log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR + ":{}", url);
      e.printStackTrace();
    }
    return null;
  }

  /**
   * post 图片上传返回 jsonStr
   *
   * @param url
   * @param file
   * @return
   */
  public static String doPostUpload(String url, MultipartFile file) {
    try {
      Response response = FastHttpClient.post().url(url)
          .addFile(file.getOriginalFilename(), file.getName(), file.getInputStream()).build()
          .execute();
      if (response.isSuccessful()) {
        String result = response.string();
        WeConResultBaseDTO weConResultBaseDTO = GsonUtils
            .fromJson(result, WeConResultBaseDTO.class);
        if (!weConResultBaseDTO.getErrcode().equals(0)) {
          log.error(result);
          throw new RuntimeException(weConResultBaseDTO.getErrmsg());
        }
        return result;
      } else {
        log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR, url, response.message());
        throw new RuntimeException(response.message());
      }

    } catch (Exception e) {
      log.error(BaseMessageConf.HTTP_CLIENT_SEND_ERROR + ":{}", url);
      e.printStackTrace();
    }
    return null;
  }

  public static void main(String[] args) {

    WeConDepartmentQuery weConDepartmentQuery = new WeConDepartmentQuery();
    weConDepartmentQuery.setName("龙湖");
    System.out.println(JSON.toJSONString(weConDepartmentQuery));
    System.out.println(JsonUtils.objectToJson(weConDepartmentQuery));

  }

}
